package com.kensure.shike.user.service;

import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import co.kensure.exception.BusinessExceptionUtil;
import co.kensure.exception.ParamUtils;
import co.kensure.frame.JSBaseService;
import co.kensure.mem.CollectionUtils;
import co.kensure.mem.MapUtils;
import co.kensure.mem.NumberUtils;
import co.kensure.mem.PageInfo;
import co.kensure.mem.Utils;

import com.kensure.basekey.BaseKeyService;
import com.kensure.mycom.config.service.MyConfigService;
import com.kensure.shike.user.dao.SKUserDao;
import com.kensure.shike.user.model.SKLogin;
import com.kensure.shike.user.model.SKUser;
import com.kensure.shike.user.model.SKUserChanChu;
import com.kensure.shike.user.model.SKUserPwd;
import com.kensure.shike.user.model.SKUserVip;
import com.kensure.shike.user.model.query.SKUserListQuery;
import com.kensure.shike.zhang.model.SKUserYue;
import com.kensure.shike.zhang.service.SKUserYueService;
import com.kensure.shike.zhang.service.SkUserFansService;

/**
 * 用户表服务实现类
 * 
 * @author fankd created on 2018-9-2
 * @since
 */
@Service
public class SKUserService extends JSBaseService {

	@Resource
	private SKUserDao dao;
	@Resource
	private SKSmsService sKSmsService;
	@Resource
	private SKLoginService sKLoginService;
	@Resource
	private BaseKeyService baseKeyService;
	@Resource
	private MyConfigService myConfigService;
	@Resource
	private SKUserYueService sKUserYueService;
	@Resource
	private SKUserVipService sKUserVipService;
	@Resource
	private SkUserFansService skUserFansService;
	@Resource
	private SKUserFRService sKUserFRService;

	public SKUser selectOne(Long id) {
		return dao.selectOne(id);
	}

	public SKUserPwd selectPwd(Long id) {
		return dao.selectPwd(id);
	}

	public List<SKUser> selectByIds(Collection<Long> ids) {
		return dao.selectByIds(ids);
	}

	public List<SKUser> selectByWhere(Map<String, Object> parameters) {
		return dao.selectByWhere(parameters);
	}

	public long selectCountByWhere(Map<String, Object> parameters) {
		return dao.selectCountByWhere(parameters);
	}

	public boolean insert(SKUser obj) {
		super.beforeInsert(obj);
		obj.setId(baseKeyService.getKey("sk_user"));
		obj.setStatus(1);
		obj.setLevelCode("0001");
		SKUserYue yue = new SKUserYue();
		yue.setId(obj.getId());
		obj.setCode(obj.getId() + "");
		sKUserYueService.insert(yue);
		return dao.insert(obj);
	}

	public boolean update(SKUser obj) {
		super.beforeUpdate(obj);
		return dao.update(obj);
	}

	public boolean updateByMap(Map<String, Object> params) {
		return dao.updateByMap(params);
	}

	/**
	 * 拥有用户余额的信息
	 * 
	 * @param id
	 * @return
	 */
	public SKUser selectOneHaveYue(Long id) {
		SKUser user = selectOne(id);
		setUserYue(user);
		return user;
	}

	/**
	 * 设置用户余额的信息
	 * 
	 * @param id
	 * @return
	 */
	private void setUserYue(SKUser user) {
		SKUserYue yue = sKUserYueService.selectOne(user.getId());
		user.setYue(yue);
	}

	/**
	 * 查询用户,后端使用
	 * 
	 * @param parameters
	 * @return
	 */
	public List<SKUser> selectList(SKUserListQuery userQuery, PageInfo page) {
		Map<String, Object> parameters = MapUtils.bean2Map(userQuery, true);

		MapUtils.putPageInfo(parameters, page);
		if (!parameters.containsKey("orderby")) {
			parameters.put("orderby", "created_time desc");
		}

		List<SKUser> list = selectByWhere(parameters);
		if (CollectionUtils.isEmpty(list)) {
			return null;
		}
		for (SKUser user : list) {
			int chengyuan = getCountByRefereeId(user.getId(), "0000").intValue();
			int huiyuan = getCountByRefereeId(user.getId(), "0001").intValue();
			user.setChengyuan(chengyuan);
			user.setHuiyuan(huiyuan);
			SKUserYue yue = sKUserYueService.selectOne(user.getId());
			user.setYue(yue);
			if (user.getRefereeId() != null) {
				SKUser ref = selectOne(user.getRefereeId());
				user.setRef(ref);
			}
		}

		return list;
	}

	/**
	 * 查询用户,不分页，不排序，功能性使用
	 * 
	 * @param parameters
	 * @return
	 */
	public List<SKUser> selectList(SKUserListQuery userQuery) {
		Map<String, Object> parameters = MapUtils.bean2Map(userQuery, true);
		List<SKUser> list = selectByWhere(parameters);
		return list;
	}

	public long selectListCount(SKUserListQuery userQuery) {
		Map<String, Object> parameters = MapUtils.bean2Map(userQuery, true);
		long count = selectCountByWhere(parameters);
		return count;
	}

	/**
	 * 通过spring的本地线程变量获取req,然后获取sessionid，获取变量,如果没有，返回null
	 */
	public SKUser getUserByToken(String token) {
		SKLogin sKLogin = sKLoginService.selectByTokenId(token);
		if (sKLogin == null) {
			return null;
		}
		SKUser user = selectOne(sKLogin.getUserid());
		return user;
	}

	/**
	 * 获取当前的邀请人
	 */
	public SKUser getRefUserByToken(String token) {
		SKLogin sKLogin = sKLoginService.selectByTokenId(token);
		if (sKLogin == null) {
			return null;
		}
		SKUser user = selectOne(sKLogin.getUserid());
		SKUser ref = null;
		if (user.getRefereeId() != null) {
			ref = selectOne(user.getRefereeId());
		}
		return ref;
	}

	/**
	 * 通过code获取用户
	 */
	public SKUser getUserByCode(String code) {
		Map<String, Object> parameters = MapUtils.genMap("code", code);
		List<SKUser> list = selectByWhere(parameters);
		if (CollectionUtils.isEmpty(list)) {
			return null;
		}
		return list.get(0);
	}

	/**
	 * 通过phone获取用户
	 */
	public SKUser getUserByPhone(String phone) {
		Map<String, Object> parameters = MapUtils.genMap("phone", phone);
		List<SKUser> list = selectByWhere(parameters);
		if (CollectionUtils.isEmpty(list)) {
			return null;
		}
		return list.get(0);
	}

	/**
	 * 校验用户会话信息
	 * 
	 * @param user
	 */
	public static void checkUser(SKUser user) {
		if (user == null) {
			BusinessExceptionUtil.threwException("用户为空,请重新登录");
		}
	}

	/**
	 * 更新手机号码
	 * 
	 * @param newPhone
	 * @param verifyCode
	 */
	public void updatePhone(Long id, String newPhone) {
		if (StringUtils.isBlank(newPhone)) {
			return;
		}
		SKUser user = selectOne(id);

		if (newPhone.length() != 11) {
			BusinessExceptionUtil.threwException("电话必须是11位");
		}
		if (!newPhone.equals(user.getPhone())) {
			SKUser ouser = getUserByPhone(newPhone);
			if (ouser != null) {
				BusinessExceptionUtil.threwException("该电话号码已经有人注册！");
			}
			user.setPhone(newPhone);
			update(user);
		}
	}

	/**
	 * 根据订单修改名称和电话
	 */
	public void updatePhoneAndName(Long id, String newPhone, String name) {
		if (StringUtils.isBlank(newPhone)) {
			return;
		}
		SKUser user = selectOne(id);
		if (StringUtils.isBlank(user.getPhone())) {
			SKUser ouser = getUserByPhone(newPhone);
			if (ouser == null) {
				user.setPhone(newPhone);
				if (StringUtils.isBlank(user.getRealname())) {
					user.setRealname(name);
				}
				if (StringUtils.isBlank(user.getNickname())) {
					user.setNickname(name);
				}
				update(user);
			}
		}

	}

	/**
	 * 更新邀请人
	 * 
	 * @param newPhone
	 * @param verifyCode
	 */
	public void updateRefByCode(Long id, String code) {
		SKUser user = selectOne(id);
		if (StringUtils.isNotBlank(code)) {
			SKUser ref = getUserByCode(code);
			if (ref == null) {
				BusinessExceptionUtil.threwException("找不到邀请码");
			}
			if (user.getId().compareTo(ref.getId()) == 0) {
				BusinessExceptionUtil.threwException("自身不能为自身的邀请人");
			}
			user.setRefereeId(ref.getId());
			update(user);
		}
	}

	/**
	 * 更新邀请人
	 * 
	 * @param newPhone
	 * @param verifyCode
	 */
	public SKUser updateRefById(Long refereeId) {
		SKUser user = getUser();
		// if (user != null && user.getRefereeId() == null) {
		// user = updateRefById(user.getId(), refereeId);
		// }
		return user;
	}

	/**
	 * 更新邀请人
	 * 
	 * @param newPhone
	 * @param verifyCode
	 */
	private SKUser updateRefById(Long id, Long refereeId) {
		SKUser user = selectOne(id);
		if (refereeId != null) {
			SKUser ref = selectOne(refereeId);
			if (ref == null) {
				return user;
			}
			if (user.getId().compareTo(ref.getId()) == 0) {
				return user;
			}
			user.setRefereeId(ref.getId());
			update(user);
		}
		return user;
	}

	/**
	 * 通过推荐人获取用户列表
	 * 
	 * @return
	 */
	public List<SKUser> getListByRefereeId() {
		SKUser skuser = getUser();
		Long userid = skuser.getId();
		List<SKUser> skUsers = getListByRefereeId(userid);
		if (CollectionUtils.isNotEmpty(skUsers)) {
			for (SKUser user : skUsers) {
				SKUserChanChu chanchu = sKUserFRService.getUserChanChu(user.getId(), userid);
				user.setChanchu(chanchu);
			}
		}
		return skUsers;
	}

	/**
	 * 通过推荐人id获取用户列表
	 * 
	 * @return
	 */
	private List<SKUser> getListByRefereeId(Long userid) {
		Map<String, Object> parameters = MapUtils.genMap("refereeId", userid);
		List<SKUser> skUsers = selectByWhere(parameters);
		return skUsers;
	}

	/**
	 * 通过推荐人id获取用户成员数或会员数
	 * 
	 * @return
	 */
	public Long getCountByRefereeId(Long userid, String startLevelCode) {
		Map<String, Object> parameters = MapUtils.genMap("refereeId", userid, "startLevelCode", startLevelCode);
		Long count = selectCountByWhere(parameters);
		return count;
	}

	/**
	 * 矫正用户的会员级别包括他的上級
	 */
	@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
	public void updateLevelCode(Long userid) {
		updateSelfLevelCode(userid);
		SKUser user = selectOne(userid);
		if (user != null && user.getRefereeId() != null && user.getRefereeId() > 0) {
			updateSelfLevelCode(user.getRefereeId());
		}
		if (StringUtils.isBlank(user.getCode())) {
			updateCode(userid);
		}

	}

	/**
	 * 新增用户的code
	 */
	@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
	public void updateCode(Long userid) {
		SKUser user = selectOne(userid);
		if (StringUtils.isBlank(user.getCode())) {
			while (true) {
				String code = Utils.randomCode8();
				SKUser codeuser = getUserByCode(code);
				if (codeuser == null) {
					user.setCode(code);
					update(user);
					break;
				}
			}
		}
	}

	/**
	 * 后台设置靓号
	 * 
	 * @param userid
	 * @param code
	 */
	public void updateCode(Long userid, String code) {
		SKUser user = selectOne(userid);
		SKUser codeuser = getUserByCode(code);
		if (codeuser == null) {
			user.setCode(code);
			update(user);
		} else {
			BusinessExceptionUtil.threwException("该靓号已经使用");
		}
	}

	private void updateSelfLevelCode(Long userid) {
		SKUserVip vip = sKUserVipService.getUserVip(userid);
		SKUser user = selectOne(userid);
		if (vip != null) {
			int count = getCountByRefereeId(userid, "0001").intValue();
			int vip_bojin = NumberUtils.parseInteger(MyConfigService.getMyConfig("vip_bojin").getVal(), 100);
			int vip_huangjin = NumberUtils.parseInteger(MyConfigService.getMyConfig("vip_huangjin").getVal(), 100);
			if (vip_bojin <= count) {
				user.setLevelCode("0003");
			} else if (vip_huangjin <= count) {
				user.setLevelCode("0002");
			} else {
				user.setLevelCode("0001");
			}
			if (user.getVipTime() == null) {
				user.setVipTime(new Date());
			}

		} else {
			user.setLevelCode("0000");
		}
		update(user);

	}

	/**
	 * 用户注册并登录
	 * 
	 * @param SKUser
	 * @param QRCode
	 * @return
	 */
	@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
	public String addAndLogin(String openid, String session_key, String nickname, String topImg, Long refereeId) {
		SKUser user = selectByOpenid(openid);
		if (user == null) {
			user = register(openid, session_key, nickname, topImg, refereeId);
		} else {
			user.setSessionKey(session_key);
			user.setTopImg(topImg);
			update(user);
		}
		String session = sKLoginService.login(user);
		return session;
	}

	/**
	 * 查询微信用户id查找用户
	 * 
	 * @param parameters
	 * @return
	 */
	public SKUser selectByOpenid(String openid) {
		Map<String, Object> parameters = MapUtils.genMap("openid", openid);
		List<SKUser> list = selectByWhere(parameters);
		SKUser user = null;
		if (CollectionUtils.isNotEmpty(list)) {
			user = list.get(0);
		}
		return user;
	}

	/**
	 * 注册用户，新增用户
	 */
	@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
	private synchronized SKUser register(String openid, String session_key, String nickname, String topImg, Long refereeId) {
		// 字段校验
		ParamUtils.isBlankThrewException(openid, "openid不能为空");
		SKUser user = selectByOpenid(openid);
		if (user != null) {
			BusinessExceptionUtil.threwException("重复注册。");
		}
		user = new SKUser();
		user.setOpenid(openid);
		user.setSessionKey(session_key);
		user.setNickname(nickname);
		user.setTopImg(topImg);
		user.setRefereeId(refereeId);
		// 插入数据
		insert(user);
		return user;
	}

	/**
	 * 通过spring的本地线程变量获取req,然后获取sessionid，获取变量,如果没有，返回null
	 */
	public SKUser getUser() {
		String tokenId = SKLoginService.getTokenId();
		if (StringUtils.isBlank(tokenId)) {
			return null;
		}
		SKLogin sKLogin = sKLoginService.selectByTokenId(tokenId);
		if (sKLogin == null) {
			return null;
		}
		SKUser user = selectOne(sKLogin.getUserid());
		return user;
	}
	
	/**
	 * 
	 */
	public Long selectCountByGroup(int yhs) {
		Map<String, Object> parameters = MapUtils.genMap("yhs", yhs, "createdTime", myConfigService.selectOne("znhsj").getVal());
		Long count = dao.selectCountByGroup(parameters);
		return count;
	}

}
